#include "Path.h"

Path::Path(std::string name):Element(name)
{
	mVertexs.clear();
}

//Path::Path(std::string name, std::vector<Point> &vertexs):Element(name)
//{
//	mVertexs = vertexs;
//}

void Path::setWidth(double width)
{
	mWidth = width;
}

double Path::getWidth() const
{
	return mWidth;
}

void Path::setVertexs(std::vector<Point> &vertexs)
{
	mVertexs = vertexs;
}

// With this function, we can get all the end coordinates of path polygon.
// When we calculate the end coordinates of each inflection, we follow such pattern:
// if the direction between previous inflection and next inflection is south-east or north-west,
// the direction between ends is north-east or south-west;
// if the direction between previous inflection and next inflection is north-east or south-west,
// the direction between ends is south-east or north-west.
void Path::getVertexs(std::vector<Point> &vertexs, double buffer) const
{
	vertexs.clear();
	
	double x1, y1, x2, y2;
	EndList *head = new EndList;
	EndList *tail = new EndList;
	EndList *trackhead = head;
	EndList *tracktail = tail;
	EndList *tmp1, *tmp2;
	for(int i = 0; i != mVertexs.size(); ++i)
	{
		x1 = mVertexs[i].x;
		x2 = mVertexs[i].x;
		y1 = mVertexs[i].y;
		y2 = mVertexs[i].y;
		
		if(i == 0)
		{
			if(mVertexs[i+1].y == mVertexs[i].y)
			{
				y1 = mVertexs[i].y - mWidth / 2 - buffer;
				y2 = mVertexs[i].y + mWidth / 2 + buffer;
			}
			else if(mVertexs[i+1].x == mVertexs[i].x)
			{
				x1 = mVertexs[i].x - mWidth / 2 - buffer;
				x2 = mVertexs[i].x + mWidth / 2 + buffer;
			}
		}
		else if(i == mVertexs.size() - 1)
		{
			if(mVertexs[i-1].y == mVertexs[i].y)
			{
				y1 = mVertexs[i].y - mWidth / 2 - buffer;
				y2 = mVertexs[i].y + mWidth / 2 + buffer;
			}
			else if(mVertexs[i-1].x == mVertexs[i].x)
			{
				x1 = mVertexs[i].x - mWidth / 2 - buffer;
				x2 = mVertexs[i].x + mWidth / 2 + buffer;
			}
		}
		else
		{
			if((mVertexs[i+1].y-mVertexs[i-1].y)*(mVertexs[i+1].x-mVertexs[i-1].x) < 0)
			{
				x1 = mVertexs[i].x - mWidth / 2 - buffer;
				y1 = mVertexs[i].y - mWidth / 2 - buffer;
				x2 = mVertexs[i].x + mWidth / 2 + buffer;
				y2 = mVertexs[i].y + mWidth / 2 + buffer;
			}
			else
			{
				x1 = mVertexs[i].x - mWidth / 2 - buffer;
				y1 = mVertexs[i].y + mWidth / 2 + buffer;
				x2 = mVertexs[i].x + mWidth / 2 + buffer;
				y2 = mVertexs[i].y - mWidth / 2 - buffer;
			}
		}

		tmp1 = new EndList;
		tmp2 = new EndList;

		if(i != 0)
		{
			if(trackhead->mEnd.x == x1 || trackhead->mEnd.y == y1)
			{
				tmp1->mEnd = Point(x1, y1);
				tmp2->mEnd = Point(x2, y2);
			}
			else
			{
				tmp1->mEnd = Point(x2, y2);
				tmp2->mEnd = Point(x1, y1);
			}
		}
		else
		{
			tmp1->mEnd = Point(x1, y1);
			tmp2->mEnd = Point(x2, y2);
		}

		trackhead->mNext = tmp1;
		tmp2->mNext = tracktail;
		trackhead = tmp1;
		tracktail = tmp2;
		if(i == mVertexs.size()-1)
			trackhead->mNext = tracktail;
	}

	EndList *p = head->mNext;
	while(p->mNext != 0)
	{
		vertexs.push_back(p->mEnd);
		p = p->mNext;
	}
	p = head;
	EndList *next;
	while(p != 0)
	{
		next = p->mNext;
		delete p;
		p = next;
	}
}

